import * as THREE from 'three';
import * as loader from './core/loader.js';
import Application from './Application.js';
import Actor from './core/Actor.js';


class AppModel extends Application {
    constructor() {
        //eslint-disable-line
        super();

        this.clock = new THREE.Clock();
        this._name = 'AppModel';
    }

    init(param) {
        super.init(param);
        console.log('AppModel.init: ', param);
        // this.act = new Actor(this);

        return this;
    }
    destory() {
        console.warn('AppModel.destory: ');
        if (this && this.deactivateAllActions && typeof this.deactivateAllActions === 'function')
            this.deactivateAllActions(); //eslint-disable-line
        super.destory();
    }
    async load(filename, scaling = 1, pos = { x: 0, y: 0, z: 0 }, offset = { x: 0, y: 0, z: 0 }) {
        this.offset = offset;
        if (!filename) return;
        if (!this.meshName) this.meshName = filename;
        if (this.model) this.scene.remove(this.model);

        console.log('AppModel.load: ', ...arguments);
        // let f = `${this.staticPath}/models/${filename}`;
        // let gltf = await loader.loadGltfAsync(f).catch(e => {
        //     //eslint-disable-line
        //     // console.error('===> ', e);
        // });
        // if (gltf) {
        //     let clonedScene = gltf.scene.clone();
        //     this.model = this.createModel(clonedScene, pos, scaling);
        //     this.scene.add(this.model);

        //     this.wheels = [];
        //     this.wheels.push(
        //         // this.model.getObjectByName('wheel-fl'),
        //         // this.model.getObjectByName('wheel-fr'),
        //         // this.model.getObjectByName('wheel-rl'),
        //         // this.model.getObjectByName('wheel-rr')
        //         this.model.getObjectByName('wheel-f'),
        //         this.model.getObjectByName('wheel-r')
        //     );
        //     // console.log('AppModel.load.success: ', clonedScene, this.meshName);
        //     // console.log('AppModel.load: wheels => ', this.wheels);

        //     // let clonedMesh = clonedScene.getObjectByName(this.meshName);
        //     // console.log('AppModel.load.success: ', this.meshName, this.model, clonedMesh);
        //     this.animations = gltf.animations;
        //     // this.mixer = new THREE.AnimationMixer(clonedMesh);
        //     this.actions = {};
        //     this.animations.forEach(clip => {
        //         // let act = this.mixer.clipAction(clip);
        //         // this.actions[clip.name] = act;
        //         this.actions[clip.name] = clip;
        //     });
        //     // console.log('AppModel.load: animations => ', gltf.animations, this.actions);

        //     // let skeleton = new THREE.SkeletonHelper(gltf.scene);
        //     // skeleton.visible = false;
        //     // this.scene.add(skeleton);
        // }

        // Actor.clearCached();
        if (this.director) this.director.clearAnimationMixer();
        if (this.act) this.act.destory();
        this.act = new Actor(this);
        this.id = filename;
        let obj = await this.act.init(filename, filename, true);
        if (obj) {
            // let scale = ((o && o.modelExt && o.modelExt.m3dScale) || 1) * 0.001;
            obj.scale.set(scaling, scaling, scaling);
            obj.traverse(child => {
                //eslint-disable-line
                if (child.isMesh) {
                    child.castShadow = true;
                    if (this.settings && this.settings.wireframe) child.material.wireframe = true;
                }
            });
            obj.position.set((pos.x + this.offset.x) / 1000, (pos.y + this.offset.y) / 1000, 0);
            if (pos && pos.h) obj.rotation.z = Math.PI * pos.h;
            obj.rotation.x = 0;
            // obj.name = o.id;
            // if (h) obj.rotation.y = Math.PI * h;
            // obj.userData.vehicleId = o.id;
            // obj.traverse(c => (c.isGroup ? (c.userData.vehicleId = o.id) : undefined));
            this.model = obj;
            this.scene.add(obj);
        }
        this.animations = this.act.animations;
        this.actions = this.act.actions;
        console.warn('[AppModel] load: ', obj, this.animations, this.actions);
    }

    createModel(obj, pos, scaling) {
        // console.log('AppModel.createModel: ', obj, pos, this.settings.wireframe);
        let group = new THREE.Group();
        // obj.rotation.x = Math.PI / 2;
        obj.scale.set(scaling, scaling, scaling);
        // to solve the problem of rendering black ...
        obj.traverse(child => {
            //eslint-disable-line
            if (child.isMesh) {
                child.castShadow = true;
                if (this.settings && this.settings.wireframe) child.material.wireframe = true;
            }
        });

        group.add(obj);
        group.position.set((pos.x + this.offset.x) / 1000, (pos.y + this.offset.y) / 1000, 0);
        if (pos && pos.h) group.rotation.z = Math.PI * pos.h;
        // group.position.set(pos.x + this.offset.x, pos.y + this.offset.y, 0);
        // this.modelsGroup.add(group);
        return group;
    }

    activateAllActions() {
        if (!this.actions || !this.actions.length) return;
        console.log('AppModel.activeAllActions: ', this.actions);
        this.actions.forEach(action => {
            action.play();
        });
    }

    deactivateAllActions() {
        if (!this.actions || !this.actions.length) return;
        this.actions.forEach(action => {
            action.stop();
        });
    }

    wheelRunningChanged(val) {
        this.settings.wheelRunning = val;
    }
    wireframeChanged(val) {
        if (this.settings) this.settings.wireframe = val;
        this.model.traverse(child => {
            //eslint-disable-line
            if (child.isMesh) {
                if (this.settings && this.settings.wireframe) child.material.wireframe = true;
                else child.material.wireframe = false;
            }
        });
    }

    getActions() {
        return this.actions;
    }
    actionPlay(act, meshName) {
        // // console.warn('AppModel.actionPlay: ', act, meshName, this.meshName);
        // if (!this.actions || !this.actions[act]) return;
        // // this.actions[act].play();
        // // let action = this.mixer.clipAction(this.actions[act]);
        // if (meshName) this.meshName = meshName;
        // if (/alarm[0-9]/.test(this.meshName)) this.meshName = 'alarm-light';
        // // console.warn('AppModel.actionPlay: ', act, meshName, this.meshName);
        // // console.warn('AppModel.actionPlay: ', act, this.actions);
        // let mesh = this.model.getObjectByName(this.meshName);
        // // this.mixer = new THREE.AnimationMixer(mesh);
        // this.mixer = new THREE.AnimationMixer(this.model);
        // // let clip = THREE.AnimationClip.findByName(this.animations, act);
        // // let action = this.mixer.clipAction(clip);
        // if (this.action) {
        //     this.action.reset().fadeOut(0.2).stop();
        // }
        // this.action = this.mixer.clipAction(this.actions[act]);
        // this.action.reset().fadeIn(0.2).play();

        this.act.play(this.id, act, meshName);
    }

    running() {
        let dt = this.clock.getDelta();
        if (this.mixer) this.mixer.update(dt);

        if (!this.settings || !this.settings.wheelRunning) return;
        // console.log('===> ', this.wheels);
        if (!this.wheels || !this.wheels.length) return;
        let timer = -performance.now() / 1000;
        for (let i = 0, len = this.wheels.length; i < len; i++) {
            if (!this.wheels[i]) return;
            this.wheels[i].rotation.x = -timer * Math.PI;
        }
        if (this.artist.grid) this.artist.grid.position.x = timer % 5;
    }

    createPaths() {}
    updatePaths() {}
    createVehicles() {}
    updateVehicles() {}
}
export default AppModel;
